//
//  ConversationListViewModel.m
//  MiniWeChat
//
//  Created by ByteDance on 2025/6/25.
//

#import "ConversationListViewModel.h"
#import "MessageModel.h"
#import "DBStorageService.h"
#import "NetworkService.h"

@interface ConversationListViewModel ()

@property (nonatomic, copy) NSString *uid;
@property (nonatomic, strong) NSMutableArray<ConversationModel *> *mutableConversations;

@end

@implementation ConversationListViewModel

- (instancetype)initWithUID:(NSString *)uid {
    self = [super init];
    if (self) {
        _uid = uid;
        _mutableConversations = [NSMutableArray array];
        
        // 注册消息监听
        [self startNotificationListening];
    }
    return self;
}

- (void)startNotificationListening {
    // 监听新消息通知
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(handleReceivedNewMessageNotification:)
                                                 name:kNotificationReceivedNewMessage
                                               object:nil];
    
    // 监听会话更新通知
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(handleMarkAsReadOrUnread:)
                                                 name:kNotificationMarkAsReadOrUnread
                                               object:nil];
}

- (void)stopNotificationListening {
    [[NSNotificationCenter defaultCenter] removeObserver:self
                                                    name:kNotificationReceivedNewMessage
                                                  object:nil];
    
    [[NSNotificationCenter defaultCenter] removeObserver:self
                                                    name:kNotificationMarkAsReadOrUnread
                                                  object:nil];
}

- (void)handleReceivedNewMessageNotification:(NSNotification *)notification {
    MessageModel *message = notification.userInfo[@"message"];
    BOOL isMine = notification.userInfo[@"isMine"];
    BOOL conversationExists = NO;
    DBStorageService *storage = [DBStorageService sharedInstance];
    
    __block ConversationModel *nedUpdateConversation = nil;
    
    // 1. 更新现有会话 若会话存在
    for (ConversationModel *conversation in self.mutableConversations) {
        if ([conversation.id isEqualToString:message.conversation_id]) {
            conversation.last_msg_id = message.id;
            conversation.last_msg_content = message.content;
            conversation.last_msg_time = message.time;
            
            // 如果不是当前用户发送的消息 增加未读数
            if (![message.sender isEqualToString:self.uid]) {
                conversation.unread_count++;
            }
            
            conversationExists = YES;
            nedUpdateConversation = conversation;
            break;
        }
    }
    
    // 2. 如果会话不存在 创建新会话
    if (!conversationExists && ![message.sender isEqualToString:self.uid]) {
        [storage fetchConversationById:message.conversation_id completion:^(ConversationModel *conversation, NSError *error) {
            if (conversation) {
                conversation.last_msg_id = message.id;
                conversation.last_msg_content = message.content;
                conversation.last_msg_time = message.time;
                conversation.unread_count = 1;
                
                [self.mutableConversations addObject:conversation];
                
                // 排序并发布更新通知
                [self sortConversations];
                nedUpdateConversation = conversation;
            }
        }];
    } else {
        // 排序并发布更新通知
        [self sortConversations];
    }
    
    if (!isMine) nedUpdateConversation.last_msg_content = [NSString stringWithFormat:@"对方：%@", nedUpdateConversation.last_msg_content];
    
    // 3. 异步更新数据库
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        [storage saveConversation:nedUpdateConversation];
        [[NSNotificationCenter defaultCenter] postNotificationName:kNotificationConversationsUpdated object:self];
    });
}

- (void)handleMarkAsReadOrUnread:(NSNotification *)notification {
    ConversationModel *conversation = notification.userInfo[@"conversation"];
    if (conversation.unread_count) {
        conversation.unread_count = 0;
    } else {
        conversation.unread_count = 1;
    }
    DBStorageService *storage = [DBStorageService sharedInstance];
    [storage saveConversation:conversation];
    [[NSNotificationCenter defaultCenter] postNotificationName:kNotificationConversationsUpdated object:self];
}

- (NSInteger)numberOfConversations {
    return [_mutableConversations count];
}


- (void)sortConversations {
    [self.mutableConversations sortUsingComparator:^NSComparisonResult(ConversationModel *a, ConversationModel *b) {
        // 先按置顶排序
        if (a.is_top && !b.is_top) {
            return NSOrderedAscending;
        } else if (!a.is_top && b.is_top) {
            return NSOrderedDescending;
        }
        
        // 再按时间排序
        return [@(b.last_msg_time) compare:@(a.last_msg_time)];
    }];
}

- (void)fetchConversations {
    DBStorageService *storage = [DBStorageService sharedInstance];
    // 先从本地数据库加载
    [storage fetchConversationsByUid:self.uid completion:^(NSArray<ConversationModel *> *conversations, NSError *error) {
        if (error) {
            // 通知 View 加载失败 （本地数据库加载失败）
            return;
        }
        
        [self.mutableConversations removeAllObjects];
        [self.mutableConversations addObjectsFromArray:conversations];
        [self sortConversations];
        
        // 再从网络同步
        // 存在三种情况
        // 1. 本地数据和网络数据均存在聊天会话 数据以网络数据为准
        // 2. 本地数据存在但网络数据不存在 不修改
        // 3. 本地数据不存在但网络数据存在 新增
    }];
}

- (ConversationModel *)conversationAtIndex:(NSInteger)index {
    return [_mutableConversations objectAtIndex:index];
}

- (void)markConversationAsReadAtIndex:(NSInteger)index {
    ConversationModel *conversation = [self.mutableConversations objectAtIndex:index];
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        DBStorageService *storage = [DBStorageService sharedInstance];
        conversation.unread_count = 0;
        [storage saveConversation:conversation];
        [[NSNotificationCenter defaultCenter] postNotificationName:kNotificationConversationsUpdated object:self];
    });
}

#pragma mark - Getters

- (NSArray<ConversationModel *> *)conversations {
    return [self.mutableConversations copy];
}

#pragma mark - Notifications

- (void)dealloc {
    [self stopNotificationListening];
}

@end
